home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 1996 April / Software of the Month Club 1996 April.iso / pc / os2 / psutils / src / pstops.c < prev    next >
C/C++ Source or Header  |  1996-02-21  |  5KB  |  199 lines

  1. /* pstops.c
  2.  * Copyright (C) Angus J. C. Duggan 1991-1995
  3.  * See file LICENSE for details.
  4.  *
  5.  * rearrange pages in conforming PS file for printing in signatures
  6.  *
  7.  * Usage:
  8.  *       pstops [-q] [-b] [-d] [-w<dim>] [-h<dim>] [-ppaper] <pagespecs> [infile [outfile]]
  9.  */
  10.  
  11. #include "psutil.h"
  12. #include "psspec.h"
  13. #include "pserror.h"
  14. #include "patchlev.h"
  15.  
  16. char *program ;
  17. int pages ;
  18. int verbose ;
  19. FILE *infile ;
  20. FILE *outfile ;
  21. char pagelabel[BUFSIZ] ;
  22. int pageno ;
  23.  
  24. void usage(void)
  25. {
  26.    fprintf(stderr, "%s release %d patchlevel %d\n", program, RELEASE, PATCHLEVEL);
  27.    fprintf(stderr, "Copyright (C) Angus J. C. Duggan, 1991-1995. See file LICENSE for details.\n");
  28.    fprintf(stderr, "Usage: %s [-q] [-b] [-wwidth] [-hheight] [-dlwidth] [-ppaper] <pagespecs> [infile [outfile]]\n",
  29.        program);
  30.    fflush(stderr);
  31.    exit(1);
  32. }
  33.  
  34. static void argerror(void)
  35. {
  36.    fprintf(stderr, "%s: page specification error:\n", program);
  37.    fprintf(stderr, "  <pagespecs> = [modulo:]<spec>\n");
  38.    fprintf(stderr, "  <spec>      = [-]pageno[@scale][L|R|U][(xoff,yoff)][,spec|+spec]\n");
  39.    fprintf(stderr, "                modulo>=1, 0<=pageno<modulo\n");
  40.    fflush(stderr);
  41.    exit(1);
  42. }
  43.  
  44. static int modulo = 1;
  45. static int pagesperspec = 1;
  46.  
  47. static PageSpec *parsespecs(char *str)
  48. {
  49.    PageSpec *head, *tail;
  50.    int other = 0;
  51.    int num = -1;
  52.  
  53.    head = tail = newspec();
  54.    while (*str) {
  55.       if (isdigit(*str)) {
  56.      num = parseint(&str, argerror);
  57.       } else {
  58.      switch (*str++) {
  59.      case ':':
  60.         if (other || head != tail || num < 1) argerror();
  61.         modulo = num;
  62.         num = -1;
  63.         break;
  64.      case '-':
  65.         tail->reversed = !tail->reversed;
  66.         break;
  67.      case '@':
  68.         if (num < 0) argerror();
  69.         tail->scale *= parsedouble(&str, argerror);
  70.         tail->flags |= SCALE;
  71.         break;
  72.      case 'l': case 'L':
  73.         tail->rotate += 90;
  74.         tail->flags |= ROTATE;
  75.         break;
  76.      case 'r': case 'R':
  77.         tail->rotate -= 90;
  78.         tail->flags |= ROTATE;
  79.         break;
  80.      case 'u': case 'U':
  81.         tail->rotate += 180;
  82.         tail->flags |= ROTATE;
  83.         break;
  84.      case '(':
  85.         tail->xoff += parsedimen(&str, argerror);
  86.         if (*str++ != ',') argerror();
  87.         tail->yoff += parsedimen(&str, argerror);
  88.         if (*str++ != ')') argerror();
  89.         tail->flags |= OFFSET;
  90.         break;
  91.      case '+':
  92.         tail->flags |= ADD_NEXT;
  93.      case ',':
  94.         if (num < 0 || num >= modulo) argerror();
  95.         if ((tail->flags & ADD_NEXT) == 0)
  96.            pagesperspec++;
  97.         tail->pageno = num;
  98.         tail->next = newspec();
  99.         tail = tail->next;
  100.         num = -1;
  101.         break;
  102.      default:
  103.         argerror();
  104.      }
  105.      other = 1;
  106.       }
  107.    }
  108.    if (num >= modulo)
  109.       argerror();
  110.    else if (num >= 0)
  111.       tail->pageno = num;
  112.    return (head);
  113. }
  114.  
  115. void main(int argc, char *argv[])
  116. {
  117.    PageSpec *specs = NULL;
  118.    int nobinding = 0;
  119.    double draw = 0;
  120.    Paper *paper;
  121.  
  122. #ifdef PAPER
  123.    if ( (paper = findpaper(PAPER)) != (Paper *)0 ) {
  124.       width = (double)PaperWidth(paper);
  125.       height = (double)PaperHeight(paper);
  126.    }
  127. #endif
  128.  
  129.    infile = stdin;
  130.    outfile = stdout;
  131.    verbose = 1;
  132.    for (program = *argv++; --argc; argv++) {
  133.       if (argv[0][0] == '-') {
  134.      switch (argv[0][1]) {
  135.      case 'q':    /* quiet */
  136.         verbose = 0;
  137.         break;
  138.      case 'd':    /* draw borders */
  139.         if (argv[0][2])
  140.            draw = singledimen(*argv+2, argerror, usage);
  141.         else
  142.            draw = 1;
  143.         break;
  144.      case 'b':    /* no bind operator */
  145.         nobinding = 1;
  146.         break;
  147.      case 'w':    /* page width */
  148.         width = singledimen(*argv+2, argerror, usage);
  149.         break;
  150.      case 'h':    /* page height */
  151.         height = singledimen(*argv+2, argerror, usage);
  152.         break;
  153.      case 'p':    /* paper type */
  154.         if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
  155.            width = (double)PaperWidth(paper);
  156.            height = (double)PaperHeight(paper);
  157.         } else
  158.           message(FATAL, "paper size '%s' not recognised\n", *argv+2);
  159.         break;
  160.      case 'v':    /* version */
  161.         usage();
  162.      default:
  163.         if (specs == NULL)
  164.            specs = parsespecs(*argv);
  165.         else
  166.            usage();
  167.      }
  168.       } else if (specs == NULL)
  169.      specs = parsespecs(*argv);
  170.       else if (infile == stdin) {
  171.      if ((infile = fopen(*argv, OPEN_READ)) == NULL)
  172.         message(FATAL, "can't open input file %s\n", *argv);
  173.       } else if (outfile == stdout) {
  174.      if ((outfile = fopen(*argv, OPEN_WRITE)) == NULL)
  175.         message(FATAL, "can't open output file %s\n", *argv);
  176.       } else usage();
  177.    }
  178.    if (specs == NULL)
  179.       usage();
  180. #if defined(MSDOS) || defined(WINNT)
  181.    if ( infile == stdin ) {
  182.       int fd = fileno(stdin) ;
  183.       if ( setmode(fd, O_BINARY) < 0 )
  184.          message(FATAL, "can't open input file %s\n", argv[4]);
  185.     }
  186.    if ( outfile == stdout ) {
  187.       int fd = fileno(stdout) ;
  188.       if ( setmode(fd, O_BINARY) < 0 )
  189.          message(FATAL, "can't reset stdout to binary mode\n");
  190.     }
  191. #endif
  192.    if ((infile=seekable(infile))==NULL)
  193.       message(FATAL, "can't seek input\n");
  194.  
  195.    pstops(modulo, pagesperspec, nobinding, specs, draw);
  196.  
  197.    exit(0);
  198. }
  199.